import base64
import hashlib
import json
import os
import random
import socket
import time
from urllib import parse

import paramiko
import requests
import traceback
import speech_recognition as sr
from PyQt5.QtCore import QSettings, pyqtSignal
from selenium import webdriver

from cmomon import NetAddressAsr, NetAddressTTS, NetAddressNip
from util.sdk.TXTool import requestExample
from util.sdk.TXrealtime import sendVoice

settings = QSettings(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "config\\config.ini"),
                     QSettings.IniFormat)
settings.setIniCodec("UTF-8")


class Tools:
    @staticmethod
    def resource_path(fileName):
        curpath = os.path.dirname(os.path.abspath(__file__))
        root = curpath.replace("util", "")
        print(root + fileName)
        return root + fileName


def net_is_used(port, ip='127.0.0.1'):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect((ip, port))
        s.shutdown(2)
        return True
    except:
        return False




def recvoicedemo(fileName,rate=16000):

    r = sr.Recognizer()
    with sr.Microphone(sample_rate=rate) as source:
        print("please say something")
        audio = r.listen(source)
    with open(fileName, "wb") as f:
        f.write(audio.get_wav_data())

def demotext():
    try:
        baseFile = os.path.dirname(os.path.abspath(__file__))
        FileName = os.path.join(baseFile, "input.wav")

        recvoicedemo(FileName)
        ret = sendVoice(FileName,True)
        # ret = requestExample(FileName)
        obj = json.loads(ret)
        print(obj["text"])
        if len(obj["text"]) > 0:
            InsturcDict = {}
            InsturcDict["AsrComent"] = obj["text"]
            InsturcDict["InstrucId"] = 1
            InsturcDict["Success"] = True
            print(InsturcDict)
            # self.tapeing = False
            # self.tcp_action_signal.emit(InsturcDict)
        else:
            demotext()
            # tapeing = True
            # InsturcDict = {}
            # InsturcDict["AsrComent"] = "语音识别失败！请再来一次"
            # InsturcDict["InstrucId"] = 1
            # InsturcDict["Success"] = False
            # self.tcp_action_signal.emit(InsturcDict)

        # self.waveshardsend(self.Client, RecordDate)
    except Exception:
        print(traceback.format_exc())


def DownloadImage(path, imageName, stp, stpDownlldpat, obj):
    try:
        if os.path.exists(stpDownlldpat + '/' + path):
            if os.path.exists(stpDownlldpat + '\\' + path + '\\' + imageName):
                pass
            else:
                stp.get(settings.value("DownloadSSH/PutHostPath")+ '/' + path + '/' + imageName,
                        stpDownlldpat + '\\' + path + '\\' + imageName)
        else:
            os.mkdir(stpDownlldpat + '/' + path)
            stp.get(settings.value("DownloadSSH/PutHostPath") + '/' + path + '/' + imageName,
                    stpDownlldpat + '\\' + path + '\\' + imageName)

    except Exception as f:
        print(f)

def reduceitem(item):
    return item.split(".")[0]


def GetChromeDrive(client, version,stpDownlldpat):
    Sftp = client.open_sftp()
    Sftp.get(settings.value("DownloadSSH/ChromeDriveHostPath") + '/' + version + '/' + "chromedriver.exe",
             stpDownlldpat)

def sshChrome(sys_ip,username,password,stpDownlldpat):
    try:
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(sys_ip, 22, username=username, password=password, timeout=20)
        Sftp = client.open_sftp()
        opt = webdriver.ChromeOptions()
        opt.headless = True
        driver = webdriver.Chrome(options=opt)
        driver.close()
        ItemVersion = driver.capabilities["version"]
        version = reduceitem(ItemVersion)
        GetChromeDrive(client, version, stpDownlldpat)
        Sftp.close()
        client.close()
    except Exception as f:
        print(f)


# 远程登陆操作系统
def ssh(sys_ip, username, password, stpDownlldpat, obj=None):
    try:
        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(sys_ip, 22, username=username, password=password, timeout=20)
        stdin, stdout, stderr = client.exec_command('cd ' + settings.value("DownloadSSH/PutHostPath") + ';ls')
        result_ls = stdout.readlines()
        Sftp = client.open_sftp()
        for i in result_ls:
            file_path = i.replace('\n', '')
            stdin, stdout, stderr = client.exec_command(
                'cd ' + settings.value("DownloadSSH/PutHostPath") + '/' + file_path + ';ls')
            ImageNameList = stdout.readlines()
            for ImageName in ImageNameList:
                image = ImageName.replace('\n', '')
                DownloadImage(file_path, image, Sftp, stpDownlldpat, obj)

    except Exception as f:
        print(f)
    finally:
        Sftp.close()
        client.close()


import pyaudio
import wave


def SpeechVoice(CHUNK, vociepath):
    p = pyaudio.PyAudio()
    wf = wave.open(vociepath, 'rb')
    stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                    channels=wf.getnchannels(),
                    rate=wf.getframerate(),
                    output=True)

    data = wf.readframes(int(CHUNK))
    while len(data) > 0:
        stream.write(data)
        data = wf.readframes(int(CHUNK))
    stream.stop_stream()
    stream.close()
    p.terminate()


def deleVoiceFile(vociepath, fileName):
    '''删除文件'''
    if (os.path.exists(vociepath + fileName)):
        os.remove(vociepath + fileName)


def GetHttpDate(url, params, method=None):
    if method != None:
        if method.upper() == "GET":
            ret = requests.get(url=url, params=params)
            date = ret.content.decode("utf-8")
            item = json.loads(date)
            return item
        elif method.upper() == "POST":
            it_date = json.dumps(params)
            ret = requests.post(url=url, data=it_date)
            date = ret.content.decode("utf-8")
            item = json.loads(date)
            return item

def GetPathChromeDrive(BasePath):
    BASE_PATH_CHROME = os.path.join(BasePath, "ChromeDrive")
    CHROMEDRIVE_PATH = os.path.join(BASE_PATH_CHROME,"chromedriver.exe")
    if os.path.exists(BASE_PATH_CHROME):
        pass
    else:
        os.makedirs(BASE_PATH_CHROME,mode=555)
    if os.path.exists(CHROMEDRIVE_PATH):
        print("有了，更新考虑")
    else:
        sshChrome(settings.value("DownloadSSH/SSH_IP"),settings.value("DownloadSSH/UserName"),settings.value("DownloadSSH/PassWord"),CHROMEDRIVE_PATH)

def GetPathImage(BasePath):
    BASE_PATH_Image =os.path.join(BasePath,"image")
    if os.path.exists(BASE_PATH_Image):
        ssh(settings.value("DownloadSSH/SSH_IP"),settings.value("DownloadSSH/UserName"),settings.value("DownloadSSH/PassWord"), BASE_PATH_Image)
    else:
        os.makedirs(BASE_PATH_Image, mode=555)
        ssh(settings.value("DownloadSSH/SSH_IP"),settings.value("DownloadSSH/UserName"),settings.value("DownloadSSH/PassWord"), BASE_PATH_Image)

def GreatLOG(BasePath):
    log = os.path.join(BasePath,"logs")
    logLine = os.path.join(BasePath,"logs\\pmsspider.log")
    if os.path.exists(log):
        pass
    else:
        os.mkdir(log)
    if os.path.exists(logLine):
        pass
    else:
        with open(logLine, mode='a', encoding='utf-8') as ff:
            ff.close()



def InitItrm():
    GreatLOG()


def requestprame():
    '''NIP对答请求参数'''
    item = {
            "question":None,       # string 用户的真实问句，发送时需进行UrlEncode
            "pubkey":settings.value("TXY_KEY/pubkey"),                 # string  分配的PubKey，发送时需要进行UrlEncode
            "account":15719190166,                # string 提问者的唯一标识（如：手机号）
            "ip":'127.0.0.1',                     # string（可选）    客户端ip，用于统计地域信息，用于热点分析
            "sessionId":None,              # string  会话Id，仅支持英文
            "time_stamp": time.time(),             # string 当前时间戳，可记录发起请求的时间，单位精确到秒
            # "client":None                 # String（可选）    不同的渠道，wechat、app、pc、可以填写: '-'，仅支持英文
            # "im":None,                     # string（可选）    不同的厂商，yiconnect、live800，可以填写: '-'，仅支持英文
            # "labels":None,                 # string（可选）    (多答案或者vip用户)# 答案标签，标签可以有多个，仅支持英文
            # "cid":None,                    # string（可选）    （kf客服、user用户、agent代理人、in_user内部用户)，坐席辅助必填字段，仅支持英文
            # "eid":None                     # string（可选）    业务入口，火车票、机票等，仅支持英文
    }
    return item

def randstr(n):
    seed = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    sa = []
    for i in range(n):
        sa.append(random.choice(seed))
    salt = ''.join(sa)
    # print salt
    return salt

def Getsigin(item):
    # baseitem = base64.b64encode(item.encode("utf-8"))
    baseitem = base64.b64encode(item.encode("utf-8"))
    md5item = hashlib.md5(baseitem)
    return md5item.hexdigest()

def GetRawStr(sortDict):
    value = ""
    for item in sortDict:
        value+=str(item[1])
    return value+settings.value("TXY_KEY/SECRET_KEY")

def GetUrl(Url,sortDict,sigin):
    Url=Url+'?'  # ip:port/yibot/query?
    nim = ""
    for item in sortDict:
        nim = nim+'&'+item[0]+'='+str(item[1])
    return Url+nim+'&'+'sign'+'='+sigin
    pass

def GetVoiceByTTS(quesion):
    '''
    todo TTS
    :param quesion:
    :return:
    '''
    print("太转化为语音的文字：")
    print(quesion)
    req_url=NetAddressTTS
    header = {
        "Content-Type": "application/json",
    }
    request_data = {
        "AppId": 1255824371,
        "SecretId": "AKID3wb2D8EFRN3UgbwengJ5h5E8nERPabqq",
        "PrimaryLanguage": 1,
        "SampleRate": 16000,
        "Action": "TextToStreamAudio",
        "VoiceType": 1,
        "Text": "我只是拿来测试的⽂本",
        "SessionId": "session-1234",
        "Speed": 0,
        "Volume": 0
    }
    r = requests.post(req_url, headers=header, data=request_data)
    file_object = open("./test.pcm", "w")
    for chunk in r.iter_content(1000):
        file_object.write(chunk)
    file_object.close()


def GetRequests(conment):
    '''
    todo NIP交互
    :param conment: 原始问题
    :return:
    '''
    #
    url = "http://"+NetAddressNip+"/yibot/query"
    ret = requestprame()
    ret["question"]=conment
    ret["sessionId"] = randstr(16)
    order_item = ret
    sortDict = sorted(ret.items(),key=lambda d:d[0])
    retValueSort = GetRawStr(sortDict)
    sigin = Getsigin(retValueSort)
    puburlencode=parse.quote(settings.value("TXY_KEY/pubkey"))
    commentencode=parse.quote(conment)
    order_item["pubkey"]=puburlencode
    order_item["question"]=commentencode
    itemone = sorted(order_item.items(), key=lambda d: d[0])
    UrlMe = GetUrl(url,itemone,sigin)
    ret = requests.get(UrlMe)
    print(ret.content.decode("utf-8"))

def demoll(req_url):

    pass

def send_and_recv(headers, body):
    req_url = "http://"+NetAddressAsr+"/voice.cgi"
    r = requests.post(req_url, headers=headers, data=body, timeout=200)
    return r

def SplitRecordDate(item,AddItem):
    try:
        itemList = []
        if len(item)>0 and len(item)>AddItem:
            i = 0
            print(item[0:AddItem])
            print(len(item))
            while i <= len(item):
                itemList.append(item[i:i + AddItem])
                i += AddItem
            print(itemList)
            return True,itemList
        else:
            return False,None
    except Exception as f:
        print(f)

def NipTalkobj():
    try:
        pass
    except Exception as f:
        print(f)

def reduceNIPDate(ret):
    '''

    :param ret: NIP回包,type?json?byte?
    :return:
    '''

def splitSpeecStremSend(speechObj):
    '''

    :param speechObj:音频流对象
    :return: 识别后的音频
    '''
    pass

def speechStrmeRecognition(itemList,task):
    '''

    :param itemList:数据流列表
    :return:timelist:识别后的文字
    '''
    try:
        timelist = []
        seq_type = 0
        for index in range(len(itemList)):
            if index==len(itemList)-1:
                seq_type = 1
            header = {
                "Content-Type": "multipart/form-data;boundary=----WebKitFormBoundarybS1Fvrpes3yfBSvu",
                "Host": "115.159.78.37",
                "Content-Length": "",
            }
            body_data = "------WebKitFormBoundarybS1Fvrpes3yfBSvu\r\n"
            body_data += "Content-Disposition: form-data; name=\"para\"\r\n"
            body_data += "Content-Type: application/octet-stream\r\n\r\n"
            case_id = ""
            voice_id = str(task) + "0ijklmn"
            model_type = "0"

            tmp_seq_str = str(index)
            tmp_seq_type_str = str(seq_type)
            tmp_body_data = "{\"cmd\":0,\"case_id\":\"" + case_id + "\",\"voice_id\":\""
            tmp_body_data += voice_id + "\",\"model_type\":" + model_type + ",\"client_info\":\"55555\""
            tmp_body_data += ",\"seq\":" + tmp_seq_str + ",\"seq_type\":" + tmp_seq_type_str + ",\"voice_file_type\":1,\"voice_encode_type\":1}"
            print(tmp_body_data)

            body_data += tmp_body_data
            body_data += "\r\n"
            body_data += "------WebKitFormBoundarybS1Fvrpes3yfBSvu\r\n"
            body_data += "Content-Disposition: form-data; name=\"data\"\r\n"
            body_data += "Content-Type: application/octet-stream\r\n\r\n"
            body_data = body_data.encode()
            body_data += itemList[index]
            body_data += b"\r\n"
            body_data += b"------WebKitFormBoundarybS1Fvrpes3yfBSvu--\r\n\r\n"
            tmp_str = str(len(body_data))
            header["Content-Length"] = tmp_str
            rsp = send_and_recv(header, body_data)
            str(rsp.content)
            timelist.append(rsp.elapsed.microseconds)
        return timelist
    except Exception as f:
        print(f)







if __name__ == "__main__":
    # q = Tools()
    # r = q.resource_path("tmp\\config.ini")
    # print("----"+r)
    demotext()

